/*
 * HttpSession.java $version 2010. 12. 03
 *
 * Copyright 2010 NHN Corp. All rights Reserved. 
 * NHN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
 */
package com.nhn.android.samples.network;

import java.io.IOException;
import java.io.InputStream;

import java.net.URL;
import java.nio.channels.CancelledKeyException;

import oauth.signpost.OAuthConsumer;


import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpDelete;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpPut;
import org.apache.http.client.methods.HttpRequestBase;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.params.BasicHttpParams;
import org.apache.http.params.HttpConnectionParams;
import org.apache.http.params.HttpParams;

/**
 * @author DK SHIN
 */

public class HttpOAuthSessionSample {

	public static final int METHOD_GET = 0;
	public static final int METHOD_POST = 1;
	public static final int METHOD_DELETE = 2;
	public static final int METHOD_PUT = 3;
	
	public static final int CONTENT_TYPE_XML = 0;
	public static final int CONTENT_TYPE_JSON = 1;
	
	URL mURL = null;
	InputStream inStream = null;
	Thread mThread;
	boolean mRunning = false;
	public String mCookie;

	int mMethod = METHOD_GET;
	int mContentType = CONTENT_TYPE_XML;
	OAuthConsumer mConsumer = null;
	String viewer;

	public HttpOAuthSessionSample(HttpSessionHandler handler, OAuthConsumer consumer ) {
		mHandler = handler;
		mConsumer = consumer;
	}
	
	public void setConsumer(String token, String token_secret) {
		mConsumer.setTokenWithSecret(token, token_secret);
	}

	public boolean create() {
		return (true);
	}

	public boolean create(int method) {
		mMethod = method;
		return (true);
	}
	
	public void setContentType(int contentType) {
		mContentType = contentType;
	}
	
	public void setViewer(String viewer) {
		this.viewer = viewer;
	}
	
	public boolean open(String url) {

		try {
			mURL = new URL(url);
		} catch (Exception err) {
			return (false);
		}

		int port = mURL.getPort();
		if (port == 0 || port == -1) {
			if (mURL.getProtocol().equalsIgnoreCase("http")) {
				port = 80;
			} else {
				return (false);
			}
		}

		mThread = new Thread(new HttpClientTask(this));
		mThread.start();

		return (true);
	}

	public void close() {

		if (mThread != null) {
			try {
				mThread.join(1000);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
		mRunning = false;
		mHandler = null;

	}

	void closeSocket() {
	}

	
	HttpSessionHandler mHandler = null;
	
	public static final int TIMERA_TIMEOUT = 5 * 1000;
	public static final int TIMERB_TIMEOUT = 5 * 1000;

	/**
	 * Timer
	 * 
	 * @author n/a
	 */
	public class HttpClientTask implements Runnable {
		Object mParent;
		int mCount;

		HttpClientTask(Object parent) {
			mParent = parent;
			mCount = 0;
		}

		public void run() {
			byte[] data = new byte[4192];
			
			int length = 0;
			int tot = 0;
			try {
				mRunning = true;

				HttpParams params = new BasicHttpParams();
				HttpConnectionParams.setConnectionTimeout(params, 10000);
				HttpConnectionParams.setSoTimeout(params, 10000);


				HttpRequestBase httpRequest = null;

				//sample data format for xml
				StringBuilder xmlSampleData = new StringBuilder();
				xmlSampleData.append("<map>");
				xmlSampleData.append("<entry>");
				xmlSampleData.append("<key>name</key>");
				xmlSampleData.append("<value>John</value>");
				xmlSampleData.append("</entry>");
				xmlSampleData.append("<entry>");
				xmlSampleData.append("<key>age</key>");
				xmlSampleData.append("<value>21</value>");
				xmlSampleData.append("</entry>");
				xmlSampleData.append("<map>");
				
				//sample data format for json
				StringBuilder jsonSampleData = new StringBuilder();
				jsonSampleData.append("{");
				jsonSampleData.append("name: \"John\",age: \"21\"");
				jsonSampleData.append("}");

				if (mMethod == METHOD_GET) {
					httpRequest = new HttpGet(mURL.toURI());
				} else if (mMethod == METHOD_POST) {
					httpRequest = new HttpPost(mURL.toURI());
					
					
					if (mContentType == CONTENT_TYPE_XML) {
						((HttpPost)httpRequest).setEntity(new StringEntity(xmlSampleData.toString()));	
						httpRequest.addHeader("Content-Type", "application/xml"); 
					} else {
						((HttpPost)httpRequest).setEntity(new StringEntity(jsonSampleData.toString()));	
						httpRequest.addHeader("Content-Type", "application/json"); 	
					}
					
				} else if (mMethod == METHOD_PUT) {
					httpRequest = new HttpPut(mURL.toURI());

					if (mContentType == CONTENT_TYPE_XML) {
						((HttpPost)httpRequest).setEntity(new StringEntity(xmlSampleData.toString()));	
						httpRequest.addHeader("Content-Type", "application/xml"); 
					} else {
						((HttpPost)httpRequest).setEntity(new StringEntity(jsonSampleData.toString()));	
						httpRequest.addHeader("Content-Type", "application/json"); 
					}
		
				} else if (mMethod == METHOD_DELETE) {
					httpRequest = new HttpDelete(mURL.toURI());

				}
				
				httpRequest.addHeader("user-agent", "AND");
				httpRequest.addHeader("Viewer", viewer);
				HttpClient httpClient = new DefaultHttpClient(params);
				
				if (mConsumer != null) {
					mConsumer.sign(httpRequest);
				}
				
				HttpResponse httpResponse = httpClient.execute(httpRequest);
				
				HttpEntity entity = httpResponse.getEntity();
				inStream = entity.getContent();

				String partial = "";
				if (inStream != null && mRunning == true) {
					do {
						length = inStream.read(data, 0, 4192);
						if (length > 0) {
							tot += length;
							partial += new String(data);
							
						}
					} while (length > 0 && mRunning == true);

					inStream.close();
					inStream = null;
				}

				httpClient.getConnectionManager().shutdown();

				if (mHandler != null) {
					if (tot > 0) {
						mHandler.onResult(200, partial);
					} else {
						mHandler.onResult(400, null);
					}
				}

			} catch (Exception err) {
				err.printStackTrace();
				if (mHandler != null) {
					mHandler.onResult(400, null);
				}
			}

		}
	}

	public void connectReady() throws IOException {

	}

	public void writeReady() throws IOException {
	}

	public void readReady() throws IOException {
	}

	public void updateInterestOps() {

	}

	public void handleException(IOException ioe) {
		ioe.printStackTrace();
	}

	public void handleException(CancelledKeyException cke) {
		cke.printStackTrace();
	}

}
